From f041e5f03c0d67ca45c9e57a02e53efe5d52da50 Mon Sep 17 00:00:00 2001 From: robertl Date: Fri, 22 Sep 2006 16:54:16 +0000 Subject: [PATCH] Move endian determination to be compile-time constant determined by configure and conveniently defaulting to LE for our favorite configure-less environment. git-svn-id: http://gpsbabel.googlecode.com/svn/trunk@2368 f51c46e8-681c-474f-0cfe-069cfd0219fb --- gpsbabel/config.h.in | 4 + gpsbabel/configure | 232 +++++++++++++++++++++++++++++++++++++++++- gpsbabel/configure.in | 1 + gpsbabel/util.c | 29 ++---- 4 files changed, 242 insertions(+), 24 deletions(-) diff --git a/gpsbabel/config.h.in b/gpsbabel/config.h.in index 1bd4136c8..0e668d4f0 100644 --- a/gpsbabel/config.h.in +++ b/gpsbabel/config.h.in @@ -51,5 +51,9 @@ /* 1 to enable shapefile support */ #undef SHAPELIB_ENABLED +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + /* 1 to inhibit our use of zlib. */ #undef ZLIB_INHIBITED diff --git a/gpsbabel/configure b/gpsbabel/configure index 04f8788d1..5b2798e1e 100755 --- a/gpsbabel/configure +++ b/gpsbabel/configure @@ -2448,8 +2448,238 @@ fi -# Checks for libraries. +echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 +echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6 +if test "${ac_cv_c_bigendian+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # See if sys/param.h defines the BYTE_ORDER macro. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN + bogus endian macros +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + # It does; now see whether it defined to BIG_ENDIAN or not. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_c_bigendian=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 +# It does not; compile a test program. +if test "$cross_compiling" = yes; then + # try to guess the endianness by grepping values into an object file + ac_cv_c_bigendian=unknown + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; +short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; +void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } +short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; +short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; +void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } +int +main () +{ + _ascii (); _ebcdic (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then + ac_cv_c_bigendian=yes +fi +if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +int +main () +{ + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long l; + char c[sizeof (long)]; + } u; + u.l = 1; + exit (u.c[sizeof (long) - 1] == 1); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_c_bigendian=yes +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 +echo "${ECHO_T}$ac_cv_c_bigendian" >&6 +case $ac_cv_c_bigendian in + yes) + +cat >>confdefs.h <<\_ACEOF +#define WORDS_BIGENDIAN 1 +_ACEOF + ;; + no) + ;; + *) + { { echo "$as_me:$LINENO: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&5 +echo "$as_me: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} + { (exit 1); exit 1; }; } ;; +esac + + +# Checks for libraries. echo "$as_me:$LINENO: checking for cos in -lm" >&5 echo $ECHO_N "checking for cos in -lm... $ECHO_C" >&6 diff --git a/gpsbabel/configure.in b/gpsbabel/configure.in index baf3d0011..3e58529c5 100644 --- a/gpsbabel/configure.in +++ b/gpsbabel/configure.in @@ -30,6 +30,7 @@ AC_PROG_INSTALL AC_PROG_MAKE_SET AC_EXEEXT AC_SUBST(AC_EXEEXT) +AC_C_BIGENDIAN # Checks for libraries. AC_CHECK_LIB([m], [cos]) diff --git a/gpsbabel/util.c b/gpsbabel/util.c index 0a0356d7c..d2e48bd4a 100644 --- a/gpsbabel/util.c +++ b/gpsbabel/util.c @@ -27,8 +27,11 @@ #include #include -static int i_am_little_endian = -1; -static int doswap(void); +#if defined WORDS_BIGENDIAN +# define i_am_little_endian 0 +#else +# define i_am_little_endian 1 +#endif #ifdef DEBUG_MEM #define DEBUG_FILENAME "/tmp/gpsbabel.debug" @@ -596,8 +599,6 @@ le_read64(void *dest, const void *src) char *cdest = dest; const char *csrc = src; - doswap(); /* make sure i_am_little_endian is initialized */ - if (i_am_little_endian) { memcpy(dest, src, 8); } else { @@ -795,23 +796,6 @@ get_cache_icon(const waypoint *waypointp) return NULL; } -static int doswap() -{ - if (i_am_little_endian < 0) - { - /* On Intel, Vax and MIPs little endian, -1.0 maps to the bytes - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f and on Motorola, - SPARC, ARM, and PowerPC, it maps to - 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00. - */ - double d = 1.0; - char c[8]; - memcpy(c, &d, 8); - i_am_little_endian = (c[0] == 0); - } - return i_am_little_endian; -} - double endian_read_double(void* ptr, int read_le) { @@ -819,7 +803,7 @@ endian_read_double(void* ptr, int read_le) char r[8]; void *p; int i; - doswap(); /* make sure i_am_little_endian is initialized */ + if ( i_am_little_endian == read_le ) { p = ptr; } @@ -842,7 +826,6 @@ endian_write_double(void* ptr, double d, int write_le) int i; char *optr = ptr; - doswap(); /* make sure i_am_little_endian is initialized */ if ( i_am_little_endian == write_le ) { memcpy( ptr, &d, 8); } -- 2.30.2